/******************************************************************************
 * * contact_speed_dial.c - implementation of contact speed dial functions
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "contact_global.h"

/**
 * Update contact from speed dial list
 * param (in) Contact: Contacts_Info_t *
 * param (in) Name: INT8 *
 * param (in) Number: INT8 *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Update_Contact(Contacts_Info_t *Contact, INT8 *Name, INT8 *Number)
{
    UINT8                            i;
    UINT32                           Len;
    UINT32                           Offset;
    NV_UI_Contacts_Speed_Dial_Info_t *NvSpeedDial;

    if (NULL == Contact)
    {
        /* error */
        return;
    }

    for (i = 0; i < CONTACTS_MAX_SPEED_DIAL_KEY_NUMBER; i++)
    {
        if (  (0 == strcmp(Contact->Name, g_ContactsMng.SpeedDialList[i].Name))
           && (0 == strcmp(Contact->Number, g_ContactsMng.SpeedDialList[i].Number)))
        {
            UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Speed_Dials_Update_Contact, Name %s, Number %s\n", Contact->Name, Contact->Number);

            /* update NVM */
            Len = sizeof(Contacts_Speed_Dial_Info_t);
            if (NULL != Name)
            {
                Hal_Mem_Set(g_ContactsMng.SpeedDialList[i].Name, 0, CONTACTS_MAX_NAME_LENGTH);
                Hal_Mem_Copy(g_ContactsMng.SpeedDialList[i].Name, Name, strlen(Name));
            }
            if (NULL != Number)
            {
                Hal_Mem_Set(g_ContactsMng.SpeedDialList[i].Number, 0, CONTACTS_MAX_NUMBER_LENGTH);
                Hal_Mem_Copy(g_ContactsMng.SpeedDialList[i].Number, Number, strlen(Number));
            }
            if (  (NULL == Name)
               && (NULL == Number))
            {
                Hal_Mem_Set(&g_ContactsMng.SpeedDialList[i], 0, Len);
            }
            Len         = sizeof(NV_UI_Contacts_Speed_Dial_Info_t);
            NvSpeedDial = (NV_UI_Contacts_Speed_Dial_Info_t *)Hal_Mem_Alloc(Len);
            Hal_Mem_Set(NvSpeedDial, 0, Len);
            Hal_Mem_Copy(NvSpeedDial->Name, g_ContactsMng.SpeedDialList[i].Name, NV_CONTACTS_MAX_NAME_LEN);
            Hal_Mem_Copy(NvSpeedDial->Number, g_ContactsMng.SpeedDialList[i].Number, NV_CONTACTS_MAX_NUMBER_LEN);
            Offset = i * Len;
            if (Len !=
                UI_NV_Write_Req(NV_SECTION_UI_SPEED_DIAL_LIST, Offset, Len, (UINT8 *)NvSpeedDial))
            {
                /* error */
            }
            Hal_Mem_Free(NvSpeedDial);

            break;
        }
    }
} /* Contacts_Speed_Dials_Update_Contact */

/**
 * Callback function for handling key pressed on Contacts_Speed_Dials_Del interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Speed_Dials_Del_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UI_Normal_Label_Only_Desc_t *Interface;
    UINT8                       Index;
    UINT32                      Offset;
    UINT32                      Len;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_OK:
            /* get description for Contacts_Speed_Dials_Detail interface */
            Interface = (UI_Normal_Label_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;
            Index     = Interface->ButtonBar.ButtonL.ButtonIndex;

            if ((CONTACTS_MAX_SPEED_DIAL_KEY_NUMBER - 1) < Index)
            {
                /* error */
                return(1);
            }

            Len = sizeof(Contacts_Speed_Dial_Info_t);
            Hal_Mem_Set(&g_ContactsMng.SpeedDialList[Index], 0, Len);

            Offset = Index * Len;
            if (Len !=
                UI_NV_Write_Req(NV_SECTION_UI_SPEED_DIAL_LIST, Offset, Len, (UINT8 *)(&g_ContactsMng.SpeedDialList[Index])))
            {
                /* error */
            }

            Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS_DETAIL, NULL, NULL);
            break;

        default:
            break;
        } /* switch */
    }

    return(1);
} /* Contacts_Speed_Dials_Del_Key_Cb */

/**
 * Callback function for additional actions after Creating Contacts_Speed_dials_Del interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Del_OnCreate(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    UINT8                    Index      = Interface->ButtonBar.ButtonL.ButtonIndex;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    INT8                     *Output;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_DEL_NUM_FROM_LIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NAME_LENGTH + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n\n%s\n%s", Text, g_ContactsMng.SpeedDialList[Index].Name, g_ContactsMng.SpeedDialList[Index].Number);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Callback function for restoring state on Contacts_Speed_Dials_Del interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Del_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    UINT8                    Index      = Interface->ButtonBar.ButtonL.ButtonIndex;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    INT8                     *Output;

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_DEL;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_DEL_NUM_FROM_LIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NAME_LENGTH + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n\n%s\n%s", Text, g_ContactsMng.SpeedDialList[Index].Name, g_ContactsMng.SpeedDialList[Index].Number);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Create Contacts_Speed_Dials_Del interface
 * param (in) Index: UINT8, index in number screening list
 * return  VOID
 */
VOID Contacts_Create_Contacts_Speed_Dials_Del(UINT8 Index)
{
    UI_Normal_NoTitle_Desc_t *Interface;
    Nav_Func_List_t          FuncList;

    Interface = (UI_Normal_NoTitle_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_NoTitle_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_Normal_NoTitle_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_DEL;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)Interface;

    Interface->ContenCont.ContLabel.TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->ContenCont.ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->ContenCont.ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    Interface->ContenCont.ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    Interface->ButtonBar.ButtonL.Valid       = FALSE;
    Interface->ButtonBar.ButtonL.ButtonIndex = Index;

    Interface->ButtonBar.ButtonM.Valid = TRUE;
    Interface->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;

    Interface->ButtonBar.ButtonR.Valid = TRUE;
    Interface->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    Interface->KeyFunc = Contacts_Speed_Dials_Del_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_NoTitle_Create;
    FuncList.OnCreate       = Contacts_Speed_Dials_Del_OnCreate;
    FuncList.OnRestoreState = Contacts_Speed_Dials_Del_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS_DEL, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
}

/**
 * Action if pressing contact button on Contacts_Speed_Dials_Replace interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Speed_Dials_Replace_Btn_Contact_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    UI_Normal_Label_Only_Desc_t *Interface;
    UINT8                       Index;
    Contacts_List_t             *Contact = g_ContactsMng.InterfaceCtrl.Focus;
    UINT32                      Offset;
    UINT32                      Len;

    /* get description for Contacts_Speed_Dials_Detail interface */
    Interface = (UI_Normal_Label_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;
    Index     = Interface->ButtonBar.ButtonL.ButtonIndex;

    if ((CONTACTS_MAX_SPEED_DIAL_KEY_NUMBER - 1) < Index)
    {
        /* error */
        return;
    }

    if (0 == strlen(Contact->ContactInfo->Number))
    {
        Contacts_Create_No_Phone_Number();
        return;
    }

    Len = CONTACTS_MAX_NAME_LENGTH + CONTACTS_MAX_NUMBER_LENGTH;
    Hal_Mem_Set(&g_ContactsMng.SpeedDialList[Index], 0, Len);
    Hal_Mem_Copy(g_ContactsMng.SpeedDialList[Index].Name, Contact->ContactInfo->Name, CONTACTS_MAX_NAME_LENGTH);
    Hal_Mem_Copy(g_ContactsMng.SpeedDialList[Index].Number, Contact->ContactInfo->Number, CONTACTS_MAX_NUMBER_LENGTH);

    Offset = Index * Len;
    if (Len !=
        UI_NV_Write_Req(NV_SECTION_UI_SPEED_DIAL_LIST, Offset, Len, (UINT8 *)(&g_ContactsMng.SpeedDialList[Index])))
    {
        /* error */
    }

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS_DETAIL, NULL, NULL);
}

/**
 * Create Contacts_Speed_Dials_Replace interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Speed_Dials_Replace(VOID)
{
    Contacts_Com_Create_Select_One_Contact(ACT_ID_CONTACTS_SPEED_DIALS_REPLACE, Contacts_Speed_Dials_Replace_Btn_Contact_Cb);
}

/**
 * Action if pressing add contact button on Contacts_Speed_Dials_Option interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Speed_Dials_Option_Btn_Add_Contact_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    Contacts_Create_Contacts_Speed_Dials_Replace();
}

/**
 * Action if pressing replace contact button on Contacts_Speed_Dials_Option interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Speed_Dials_Option_Btn_Replace_Contact_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    Contacts_Create_Contacts_Speed_Dials_Replace();
}

/**
 * Action if pressing delete button on Contacts_Speed_Dials_Option interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Speed_Dials_Option_Btn_Delete_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    UI_Normal_List_Only_Desc_t *Interface =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.Ctrl;

    Contacts_Create_Contacts_Speed_Dials_Del(Interface->List.Index);
}

/**
 * Callback function for additional actions after Creating Contacts_Speed_Dials_Option interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Option_OnCreate(VOID *Ctrl)
{
    UI_Normal_List_Only_Desc_t *Interface = (UI_Normal_List_Only_Desc_t *)Ctrl;
    lv_obj_t                   *Label     = Interface->TitleBar.Label;
    INT8                       *Key;
    INT8                       Text[11] = { 0 };

    Key = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    sprintf(Text, "%s %d", Key, Interface->BtnBar.ButtonL.ButtonIndex);
    lv_label_set_text(Label, Text);
}

/**
 * Callback function for restoring state on Contacts_Speed_Dials_Option interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Option_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_List_Only_Desc_t *Interface = (UI_Normal_List_Only_Desc_t *)Ctrl;
    lv_obj_t                   *Label     = Interface->TitleBar.Label;
    INT8                       *Key;
    INT8                       Text[11] = { 0 };

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_DETAIL;

    Key = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    sprintf(Text, "%s %d", Key, Interface->BtnBar.ButtonL.ButtonIndex);
    lv_label_set_text(Label, Text);
}

/**
 * Create Contacts_Speed_Dials_Option interface
 * param (in) Index: UINT8, index in speed dials list
 * return  VOID
 */
VOID Contacts_Create_Contacts_Speed_Dials_Option(UINT8 Index)
{
    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc;
    Nav_Func_List_t            FuncList;
    UI_Button_Desc_t           *BtnList;
    UINT32                     Len;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Create_Contacts_Speed_Dials_Option, Index %d\n", Index);

    NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(NormalLstOnlyDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_OPTION;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)NormalLstOnlyDesc;

    NormalLstOnlyDesc->TitleBar.TxtId      = LV_LANG_TXT_ID_NONE;
    NormalLstOnlyDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalLstOnlyDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    if ('\0' == g_ContactsMng.SpeedDialList[Index].Name[0])
    {
        NormalLstOnlyDesc->List.ListButtonCnt = 1;
    }
    else
    {
        NormalLstOnlyDesc->List.ListButtonCnt = 2;
    }
    Len = sizeof(UI_Button_Desc_t) *
          NormalLstOnlyDesc->List.ListButtonCnt;
    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);
    BtnList = NormalLstOnlyDesc->List.ButtonList;

    if ('\0' == g_ContactsMng.SpeedDialList[Index].Name[0])
    {
        BtnList[0].Valid       = TRUE;
        BtnList[0].ButtonIndex = 0;
        BtnList[0].TxtId       = PHONE_TEXT_ID_ADD_CONTACT;
        BtnList[0].ReleaseFun  = Contacts_Speed_Dials_Option_Btn_Add_Contact_Cb;
    }
    else
    {
        BtnList[0].Valid       = TRUE;
        BtnList[0].ButtonIndex = 0;
        BtnList[0].TxtId       = PHONE_TEXT_ID_REPLACE_CONTACT;
        BtnList[0].ReleaseFun  = Contacts_Speed_Dials_Option_Btn_Replace_Contact_Cb;

        BtnList[1].Valid       = TRUE;
        BtnList[1].ButtonIndex = 1;
        BtnList[1].TxtId       = PHONE_TEXT_ID_DELETE;
        BtnList[1].ReleaseFun  = Contacts_Speed_Dials_Option_Btn_Delete_Cb;
    }

    NormalLstOnlyDesc->BtnBar.ButtonL.Valid       = FALSE;
    NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex = Index;

    NormalLstOnlyDesc->BtnBar.ButtonM.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;

    NormalLstOnlyDesc->BtnBar.ButtonR.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    NormalLstOnlyDesc->KeyFunc = Contacts_Normal_List_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_List_Only_Create;
    FuncList.OnCreate       = Contacts_Speed_Dials_Option_OnCreate;
    FuncList.OnRestoreState = Contacts_Speed_Dials_Option_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Normal_List_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS_OPTION, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
} /* Contacts_Create_Contacts_Speed_Dials_Option */

/**
 * Callback function for handling key pressed on Contacts_Speed_Dials_Detail interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Speed_Dials_Detail_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UI_Normal_Label_Only_Desc_t *Interface =
        (UI_Normal_Label_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;
    UINT8                       Index = Interface->ButtonBar.ButtonL.ButtonIndex;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTLEFT:
            Contacts_Create_Contacts_Speed_Dials_Option(Index);
            break;

        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        default:
            break;
        } /* switch */
    }

    return(1);
}

/**
 * Callback function for additional actions after Creating Contacts_Speed_Dials_Detail interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Detail_OnCreate(VOID *Ctrl)
{
    UI_Normal_Label_Only_Desc_t *Interface = (UI_Normal_Label_Only_Desc_t *)Ctrl;
    lv_obj_t                    *Label     = Interface->ContLabel.Label;
    UINT8                       Index      = Interface->ButtonBar.ButtonL.ButtonIndex;
    INT8                        *Text;
    INT8                        *Key;
    INT8                        *Empty;
    UINT8                       Len;

    Key   = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    Empty = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_EMPTY);

    if ('\0' == g_ContactsMng.SpeedDialList[Index].Name[0])
    {
        Len  = strlen(Key) + 4 + strlen(Empty) + 1;
        Text = (INT8 *)Hal_Mem_Alloc(Len);
        sprintf(Text, "%s %d:\n%s", Key, Index + 2, Empty);
    }
    else
    {
        Len  = strlen(Key) + 4 + strlen(g_ContactsMng.SpeedDialList[Index].Name) + 1 + strlen(g_ContactsMng.SpeedDialList[Index].Number) + 1;
        Text = (INT8 *)Hal_Mem_Alloc(Len);
        sprintf(Text, "%s %d:\n%s\n%s", Key, Index + 2, g_ContactsMng.SpeedDialList[Index].Name, g_ContactsMng.SpeedDialList[Index].Number);
    }
    lv_label_set_text(Label, Text);
    Hal_Mem_Free(Text);
}

/**
 * Callback function for restoring state on Contacts_Speed_Dials_Detail interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Detail_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_Label_Only_Desc_t *Interface = (UI_Normal_Label_Only_Desc_t *)Ctrl;
    lv_obj_t                    *Label     = Interface->ContLabel.Label;
    UINT8                       Index      = Interface->ButtonBar.ButtonL.ButtonIndex;
    INT8                        *Text;
    INT8                        *Key;
    INT8                        *Empty;
    UINT8                       Len;

    g_ContactsMng.InterfaceCtrl.PrevCtrl    = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_DETAIL;

    Key   = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    Empty = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_EMPTY);

    if ('\0' == g_ContactsMng.SpeedDialList[Index].Name[0])
    {
        Len  = strlen(Key) + 4 + strlen(Empty) + 1;
        Text = (INT8 *)Hal_Mem_Alloc(Len);
        sprintf(Text, "%s %d:\n%s", Key, Index + 2, Empty);
    }
    else
    {
        Len  = strlen(Key) + 4 + strlen(g_ContactsMng.SpeedDialList[Index].Name) + 1 + strlen(g_ContactsMng.SpeedDialList[Index].Number) + 1;
        Text = (INT8 *)Hal_Mem_Alloc(Len);
        sprintf(Text, "%s %d:\n%s\n%s", Key, Index + 2, g_ContactsMng.SpeedDialList[Index].Name, g_ContactsMng.SpeedDialList[Index].Number);
    }
    lv_label_set_text(Label, Text);
    Hal_Mem_Free(Text);
}

/**
 * Callback function for destroying state on Contacts_Speed_Dials_Detail interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_Detail_OnDestroy(VOID *Ctrl)
{
    Contacts_Interface_OnDestroy(Ctrl);
    g_ContactsMng.InterfaceCtrl.PrevCtrl = NULL;
}

/**
 * Create Contacts_Speed_Dials_Detail interface
 * param (in) Index: UINT8, index in speed dials list
 * return  VOID
 */
VOID Contacts_Create_Contacts_Speed_Dials_Detail(UINT8 Index)
{
    UI_Normal_Label_Only_Desc_t *Interface;
    Nav_Func_List_t             FuncList;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Create_Contacts_Speed_Dials_Detail, Index %d\n", Index);

    Interface = (UI_Normal_Label_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_Label_Only_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_Normal_Label_Only_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS_DETAIL;
    g_ContactsMng.InterfaceCtrl.PrevCtrl    = (VOID *)Interface;

    Interface->TitleBar.TxtId      = PHONE_TEXT_ID_SPEED_DIALS;
    Interface->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    Interface->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    Interface->ContLabel.TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    Interface->ButtonBar.ButtonL.Valid       = TRUE;
    Interface->ButtonBar.ButtonL.TxtId       = PHONE_TEXT_ID_OPT;
    Interface->ButtonBar.ButtonL.ButtonIndex = Index;

    Interface->ButtonBar.ButtonM.Valid = FALSE;

    Interface->ButtonBar.ButtonR.Valid = TRUE;
    Interface->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    Interface->KeyFunc = Contacts_Speed_Dials_Detail_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_Label_Only_Create;
    FuncList.OnCreate       = Contacts_Speed_Dials_Detail_OnCreate;
    FuncList.OnRestoreState = Contacts_Speed_Dials_Detail_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Speed_Dials_Detail_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS_DETAIL, &FuncList, g_ContactsMng.InterfaceCtrl.PrevCtrl);
}

/**
 * Action if pressing key button on Contacts_Speed_Dials interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Speed_Dials_Btn_Key_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.Ctrl;

    Contacts_Create_Contacts_Speed_Dials_Detail(NormalLstOnlyDesc->List.Index);
}

/**
 * Callback function for restoring state on Contacts_Speed_Dials interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Speed_Dials_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_List_Only_Desc_t *Interface = (UI_Normal_List_Only_Desc_t *)Ctrl;
    UINT8                      Index      = Interface->List.Index;
    UI_Button_Desc_t           *BtnList   = &Interface->List.ButtonList[Index];
    lv_obj_t                   *Label     = lv_obj_get_child(BtnList->Button, NULL);
    INT8                       *Key       = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    UINT8                      Len        = strlen(Key) + 3; // key <key value>
    UINT8                      NameLen    = strlen(g_ContactsMng.SpeedDialList[Index].Name);

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS;

    if (NULL != BtnList->BtnTxt)
    {
        Hal_Mem_Free(BtnList->BtnTxt);
    }

    if (0 != NameLen)
    {
        Len            += 1 + NameLen; // key <key value> <contact name>
        BtnList->BtnTxt = (INT8 *)Hal_Mem_Alloc(Len);
        Hal_Mem_Set(BtnList->BtnTxt, 0, Len);
        sprintf(BtnList->BtnTxt, "%s %d %s", Key, (Index + 2), g_ContactsMng.SpeedDialList[Index].Name);
    }
    else
    {
        BtnList->BtnTxt = (INT8 *)Hal_Mem_Alloc(Len);
        Hal_Mem_Set(BtnList->BtnTxt, 0, Len);
        sprintf(BtnList->BtnTxt, "%s %d", Key, (Index + 2));
    }
    lv_label_set_text(Label, BtnList->BtnTxt);
}

/**
 * Create Contacts_Speed_Dials interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Speed_Dials(VOID)
{
    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc;
    UI_Button_Desc_t           *BtnList;
    Nav_Func_List_t            FuncList;
    UINT8                      i;
    INT8                       *Key;
    UINT8                      StringLen;
    UINT32                     Len;

    NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(NormalLstOnlyDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_SPEED_DIALS;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)NormalLstOnlyDesc;

    NormalLstOnlyDesc->TitleBar.TxtId      = PHONE_TEXT_ID_SPEED_DIALS;
    NormalLstOnlyDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalLstOnlyDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    NormalLstOnlyDesc->List.ListButtonCnt = CONTACTS_MAX_SPEED_DIAL_KEY_NUMBER;
    Len                                   = sizeof(UI_Button_Desc_t) *
                                            NormalLstOnlyDesc->List.ListButtonCnt;
    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);
    BtnList = NormalLstOnlyDesc->List.ButtonList;

    Key       = (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_KEY);
    StringLen = strlen(Key) + 3; // key <key value>
    for (i = 0; i < CONTACTS_MAX_SPEED_DIAL_KEY_NUMBER; i++)
    {
        BtnList[i].Valid       = TRUE;
        BtnList[i].ButtonIndex = i;
        BtnList[i].TxtId       = LV_LANG_TXT_ID_NONE;
        BtnList[i].ReleaseFun  = Contacts_Speed_Dials_Btn_Key_Cb;

        if ('\0' != g_ContactsMng.SpeedDialList[i].Name[0])
        {
            Len               = StringLen + 1 + strlen(g_ContactsMng.SpeedDialList[i].Name);
            BtnList[i].BtnTxt = (INT8 *)Hal_Mem_Alloc(Len);
            sprintf(BtnList[i].BtnTxt, "%s %d %s", Key, (i + 2), g_ContactsMng.SpeedDialList[i].Name);
        }
        else
        {
            BtnList[i].BtnTxt = (INT8 *)Hal_Mem_Alloc(StringLen);
            sprintf(BtnList[i].BtnTxt, "%s %d", Key, (i + 2));
        }
    }

    NormalLstOnlyDesc->BtnBar.ButtonL.Valid = FALSE;

    NormalLstOnlyDesc->BtnBar.ButtonM.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_DETAILS;

    NormalLstOnlyDesc->BtnBar.ButtonR.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    NormalLstOnlyDesc->KeyFunc = Contacts_Normal_List_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_List_Only_Create;
    FuncList.OnRestoreState = Contacts_Speed_Dials_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Normal_List_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_SPEED_DIALS, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
} /* Contacts_Create_Contacts_Speed_Dials */

/**
 * Get speed dial number from contacts APP
 * param (in) Key: UINT8, digit 2 - 9
 * return  INT8*
 */
INT8 *Contacts_Get_Speed_Dial_Number_Req(UINT8 Key)
{
    UINT8 Index = Key - 2;
    UINT8 Len;
    INT8  *Number = NULL;

    if ('\0' != g_ContactsMng.SpeedDialList[Index].Name[0])
    {
        Len    = strlen(g_ContactsMng.SpeedDialList[Index].Number) + 1;
        Number = (INT8 *)Hal_Mem_Alloc(Len);
        Hal_Mem_Copy(Number, g_ContactsMng.SpeedDialList[Index].Number, Len);
    }

    return(Number);
}
